package com.gaojun;

import com.gaojun.config.AppConfig;
import com.gaojun.service.IUserService;
import com.gaojun.service.OrderService;
import com.gaojun.service.TestFactoryBean;
import com.gaojun.service.UserService;
import org.aopalliance.aop.Advice;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.*;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.framework.ProxyFactoryBean;
import org.springframework.aop.support.StaticMethodMatcherPointcut;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.HashMap;

/**
 * @author ：gaojun
 * @date ：Created in 2022-08-02 21:23
 * @description：test
 * @modified By：
 * @version: $
 */
public class Main {
	public static void main(String[] args) {
//		AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext(AppConfig.class);
		UserService target=new UserService();
		ProxyFactory proxyFactory=new ProxyFactory();
		proxyFactory.setTarget(target);
		proxyFactory.addAdvice(new MethodInterceptor() {
			@Nullable
			@Override
			public Object invoke(@Nonnull MethodInvocation invocation) throws Throwable {
				System.out.println("before............");
				Object result=invocation.proceed();
				System.out.println("after.............");
				return result;
			}
		});
		Proxy.newProxyInstance(UserService.class.getClassLoader(), new Class[]{
				IUserService.class
		}, new InvocationHandler() {
			@Override
			public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
				method.invoke(args);
				return null;
			}
		});

		ProxyFactory proxyFactory1=new ProxyFactory();
		proxyFactory1.setTarget(target);
		proxyFactory1.addAdvisor(new PointcutAdvisor() {
			@Override
			public Pointcut getPointcut() {
				return new StaticMethodMatcherPointcut() {
					@Override
					public boolean matches(Method method, Class<?> targetClass) {
						return method.getName().equals("test");
					}
				};
			}

			@Override
			public Advice getAdvice() {
				//前置通知
//				return new MethodBeforeAdvice() {
//					@Override
//					public void before(Method method, Object[] args, Object target) throws Throwable {
//						System.out.println("before............");
//					}
//				};
				//后置返回通知
//				return new AfterReturningAdvice() {
//					@Override
//					public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
//						System.out.println("afterReturning............");
//					}
//				};

				//环绕通知
				return new MethodInterceptor() {
					@Nullable
					@Override
					public Object invoke(@Nonnull MethodInvocation invocation) throws Throwable {
						return null;
					}
				};
			}

			@Override
			public boolean isPerInstance() {
				return false;
			}
		});
		IUserService userService=(IUserService) proxyFactory.getProxy();
		userService.test();

	}
}
